/*
** main.c for printf in /home/goupil_r//tek2ed/printf
** 
** Made by robin goupil
** Login   <goupil_r@epitech.net>
** 
** Started on  Sat Nov 17 09:32:39 2012 robin goupil
** Last update Sun Nov 18 12:00:07 2012 robin goupil
*/

#include <stdlib.h>
#include <stdarg.h>
#include "my.h"

int		put_double(double nbr)
{
  my_put_nbr((int)nbr);
  nbr = (nbr - (int)nbr) * 1000000;
  if (nbr < 0)
    return (2);
  my_putchar('.');
  while ((int)nbr % 10 == 0)
    nbr = nbr / 10;
  my_put_nbr((int)nbr);
  return (2);
}

int		put_formats(char *str, int i)
{
  if (str[i + 1] == '#')
    {
      if (str[i + 2] == 'x' || str[i + 2] == 'X')
	{
	  my_putstr(str[i + 2] == 'x' ? "0x" : "0X");
	  return (i + 1);
	}
      if (str[i + 2] == 'd' || str[i + 2] == 'i' || str[i + 2] == 'p' ||
	  str[i + 2] == 's' || str[i + 2] == 'S' || str[i + 2] == 'c' ||
	  str[i + 2] == 'b' || str[i + 2] == '%' || str[i + 2] == 'o')
	return (i + 1);
    }
  return (i);
}

int		put_var_chars(va_list *list, char *str, int i)
{
  if (str[i + 1] == 'c')
    {
      my_putchar(va_arg(list, int));
      return (i + 2);
    }
  if (str[i + 1] == 's')
    {
      my_putstr(va_arg(list, char *));
      return (i + 2);
    }
  if (str[i + 1] == 'S')
    {
      my_showstr(va_arg(list, char *), "01234567");
      return (i + 2);
    }
  my_putchar(str[i]);
  return (i + 1);
}

int		put_var_2(va_list *list, char *str, int i)
{
  if (str[i + 1] == 'b')
    {
      my_putnbr_unsigned_base(va_arg(list, int), "01");
      return (i + 2);
    }
  if (str[i + 1] == 'x' || str[i + 1] == 'X')
    {
      my_putnbr_unsigned_base(va_arg(list, int), str[i + 1] == 'x' ?
			      "0123456789abcdef" : "0123456789ABCDEF");
      return (i + 2);
    }
  if (str[i + 1] == 'p')
    {
      my_putstr("0x");
      my_putnbr_long_base((long)va_arg(list, long *), "0123456789abcdef");
      return (i + 2);
    }
  if (str[i + 1] == 'n')
    {
      my_put_nbr(i);
      return (i + 2);
    }
  if (str[i + 1] == 'f')
      return (i + put_double(va_arg(list, double)));
  return (put_var_chars(list, str, i));
}

int		put_var(va_list *list, char *str, int i)
{
  i = put_formats(str, i);
  if (str[i + 1] == '%')
    {
      my_putchar('%');
      return (i + 2);
    }
  if (str[i + 1] == 'd' || str[i + 1] == 'i')
    {
      my_putnbr_base(va_arg(list, int), "0123456789");
      return (i + 2);
    }
  if (str[i + 1] == 'o')
    {
      my_putnbr_base(va_arg(list, int), "01234567");
      return (i + 2);
    }
  if (str[i + 1] == 'u')
    {
      my_put_unsigned_nbr(va_arg(list, int));
      return (i + 2);
    }
  return (put_var_2(list, str, i));
}

int		my_printf(char *str, ...)
{
  va_list	list;
  int		i;

  va_start(list, str);
  i = 0;
  while (str[i])
    {
      if (str[i] == '%')
	i = put_var(&list, str, i);
      else
	i += my_putchar(str[i]);
    }
  va_end(list);
  return (i);
}
